package cn.tedu.st.base.config;

import cn.tedu.st.base.handler.CustomerAccessDeniedHandler;
import cn.tedu.st.base.handler.LoginFailureHandler;
import cn.tedu.st.security.filter.JwtAuthenticationTokenFilter;
import cn.tedu.st.base.handler.AnonymousAuthenticationHandler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * 配置Spring Security的安全设置。
 */
@Configuration
@Slf4j
//启用Spring Security的注解功能
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * AuthenticationManager会获取用户认证信息，用于身份验证和授权。
     * 配置并暴露 AuthenticationManager 为一个 Bean
     *
     * @return 配置好的 AuthenticationManager 实例
     * @throws Exception 如果配置过程中出现异常
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        // 调用父类的 authenticationManagerBean 方法，获取并返回 AuthenticationManager 实例
        return super.authenticationManagerBean();
    }


    // 自定义的认证异常处理器
    @Autowired
    private CustomerAccessDeniedHandler customerAccessDeniedHandler;
    //自定义从数据库中加载用户特定的数据
    @Autowired
    private UserDetailsService userDetailsService;
    // 自定义的匿名认证异常处理器
    @Autowired
    private AnonymousAuthenticationHandler anonymousAuthenticationHandler;
    // 自定义的密码编码器
    @Autowired
    private PasswordEncoder passwordEncoder;
    //用户登录表单认证处理器
    @Autowired
    private LoginFailureHandler loginFailureHandler;
    //自定义过滤器，用来拦截JWT认证请求
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    /**
     * 配置认证管理器（AuthenticationManager）。
     * 将自定义的UserDetailsService设置为认证管理器的用户详情服务，
     * 并指定使用BCryptPasswordEncoder对用户密码进行加密。
     *
     * @param auth 认证管理器构建器
     * @throws Exception 如果配置过程中出现错误
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置自定义的UserDetailsService和密码编码器
        log.debug("configure(AuthenticationManagerBuilder auth)开始--设置自定义的UserDetailsService和密码编码器(passwordEncoder)");
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    /**
     * 配置HTTP安全设置。
     * - 允许所有用户访问/public/**路径下的资源。
     * - 所有其他请求都需要经过身份验证。
     * - 启用表单登录功能。
     *
     * @param http HTTP安全构建器
     * @throws Exception 如果配置过程中出现错误
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
                // 禁用CSRF保护
        http.csrf().disable();
                // 开启跨域支持
                //.cors();
        // STATELESS:无状态 表示应用程序不需要保存用户会话信息，每次请求都需要重新验证身份。
        http.sessionManagement(httpSecuritySessionManagementConfigurer ->
                httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        http.authorizeRequests()
                .antMatchers("/auth/login","/public/**","/to_login")// 登录接口开放
                .permitAll()// 允许匿名访问

                .anyRequest()// 其余任何请求
                .authenticated();// 都需要身份认证

   /*     http.authorizeHttpRequests().antMatchers("/to_login","/auth/login").permitAll()// 允许匿名访问
                 .anyRequest()// 其余任何请求
                .authenticated();// 都需要身份认证;*/
        //表单登录配置
/*        http
                // 表单登录配置
                .formLogin()
                .loginPage("/login-view") // 自定义登录页
                .loginProcessingUrl("/auth/login") // 登录提交接口
                .defaultSuccessUrl("/") // 登录成功跳转
                .failureHandler(loginFailureHandler) //用户登录认证表单失败异常处理
                .permitAll();*/


        //配置jwt过滤器执行顺序
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //配置管理器的自定义认证异常处理器
        http.exceptionHandling()
                .accessDeniedHandler(customerAccessDeniedHandler)//已登录用户访问无权限异常处理
                .authenticationEntryPoint(anonymousAuthenticationHandler);//未登录用户直接访问需认证处理



    }

    // 配置跨域规则
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许携带凭证（如 Cookie）
        config.addAllowedOrigin("http://localhost:9090"); // Vue 前端地址
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }





}
